import os
from dataclasses import dataclass
from dotenv import load_dotenv

import yaml

# 加载环境变量
load_dotenv()


@dataclass
class LLMAPIConfig:
    """LLM API配置"""
    api_key: str
    base_url: str


@dataclass
class LLMModelConfig:
    """LLM模型参数配置"""
    model_name: str
    temperature: float
    max_tokens: int
    top_p: float
    frequency_penalty: float
    presence_penalty: float
    stream: bool


@dataclass
class LLMConfig:
    """LLM总配置"""
    api: LLMAPIConfig
    model: LLMModelConfig


@dataclass
class DatabaseConfig:
    """数据库配置"""
    host: str
    port: int
    user: str
    password: str
    database: str


@dataclass
class ServerConfig:
    """服务器配置"""
    host: str
    port: int


@dataclass
class LogConfig:
    """日志配置"""
    level: str
    file: str


@dataclass
class AppConfig:
    """应用配置"""
    llm: LLMConfig
    database: DatabaseConfig
    server: ServerConfig
    log: LogConfig


class YAMLConfigManager:
    """YAML配置管理器"""

    def __init__(self, config_path: str = None):
        if config_path is None:
            # 默认配置文件路径
            current_dir = os.path.dirname(os.path.abspath(__file__))
            config_path = os.path.join(current_dir, 'config.yml')

        self._config_path = config_path
        self._config = self._load_config()

    def _load_config(self) -> AppConfig:
        """从YAML文件加载配置"""
        try:
            with open(self._config_path, 'r', encoding='utf-8') as f:
                config_data = yaml.load(f, Loader=yaml.FullLoader)

            # 创建配置对象，优先使用环境变量中的值
            return AppConfig(
                llm=LLMConfig(
                    api=LLMAPIConfig(
                        api_key=os.getenv('API_KEY', config_data.get('llm', {}).get('api', {}).get('api_key', '')),
                        base_url=os.getenv('BASE_URL', config_data.get('llm', {}).get('api', {}).get('base_url', ''))
                    ),
                    model=LLMModelConfig(
                        model_name=os.getenv('MODEL_NAME', config_data.get('llm', {}).get('model', {}).get('model_name', 'gpt-4o-mini')),
                        temperature=float(os.getenv('TEMPERATURE', config_data.get('llm', {}).get('model', {}).get('temperature', 0.7))),
                        max_tokens=int(os.getenv('MAX_TOKENS', config_data.get('llm', {}).get('model', {}).get('max_tokens', 4000))),
                        top_p=float(os.getenv('TOP_P', config_data.get('llm', {}).get('model', {}).get('top_p', 1.0))),
                        frequency_penalty=float(os.getenv('FREQUENCY_PENALTY', config_data.get('llm', {}).get('model', {}).get('frequency_penalty', 0.0))),
                        presence_penalty=float(os.getenv('PRESENCE_PENALTY', config_data.get('llm', {}).get('model', {}).get('presence_penalty', 0.0))),
                        stream=bool(os.getenv('STREAM', config_data.get('llm', {}).get('model', {}).get('stream', True)))
                    )
                ),
                database=DatabaseConfig(
                    host=os.getenv('DB_HOST', config_data.get('database', {}).get('host', 'localhost')),
                    port=int(os.getenv('DB_PORT', config_data.get('database', {}).get('port', 3306))),
                    user=os.getenv('DB_USER', config_data.get('database', {}).get('user', '')),
                    password=os.getenv('DB_PASSWORD', config_data.get('database', {}).get('password', '')),
                    database=os.getenv('DB_NAME', config_data.get('database', {}).get('database', ''))
                ),
                server=ServerConfig(
                    host=os.getenv('HOST', config_data.get('server', {}).get('host', '0.0.0.0')),
                    port=int(os.getenv('PORT', config_data.get('server', {}).get('port', 8000)))
                ),
                log=LogConfig(
                    level=os.getenv('LOG_LEVEL', config_data.get('log', {}).get('level', 'INFO')),
                    file=os.getenv('LOG_FILE', config_data.get('log', {}).get('file', 'app.log'))
                )
            )
        except Exception as e:
            print(f"加载配置文件失败: {e}")
            # 返回默认配置
            return self._get_default_config()

    def _get_default_config(self) -> AppConfig:
        """获取默认配置"""
        return AppConfig(
            llm=LLMConfig(
                api=LLMAPIConfig(
                    api_key=os.getenv('API_KEY', 'default_key'),
                    base_url=os.getenv('BASE_URL', 'https://default-url.com/api/')
                ),
                model=LLMModelConfig(
                    model_name=os.getenv('MODEL_NAME', 'gpt-4o-mini'),
                    temperature=float(os.getenv('TEMPERATURE', 0.7)),
                    max_tokens=int(os.getenv('MAX_TOKENS', 4000)),
                    top_p=float(os.getenv('TOP_P', 1.0)),
                    frequency_penalty=float(os.getenv('FREQUENCY_PENALTY', 0.0)),
                    presence_penalty=float(os.getenv('PRESENCE_PENALTY', 0.0)),
                    stream=bool(os.getenv('STREAM', True))
                )
            ),
            database=DatabaseConfig(
                host=os.getenv('DB_HOST', 'localhost'),
                port=int(os.getenv('DB_PORT', 3306)),
                user=os.getenv('DB_USER', 'root'),
                password=os.getenv('DB_PASSWORD', ''),
                database=os.getenv('DB_NAME', 'default_db')
            ),
            server=ServerConfig(
                host=os.getenv('HOST', '0.0.0.0'),
                port=int(os.getenv('PORT', 8000))
            ),
            log=LogConfig(
                level=os.getenv('LOG_LEVEL', 'INFO'),
                file=os.getenv('LOG_FILE', 'app.log')
            )
        )

    def reload_config(self) -> None:
        """重新加载配置"""
        self._config = self._load_config()

    def get_config(self) -> AppConfig:
        """获取配置"""
        return self._config

    def get_llm_config(self) -> LLMConfig:
        """获取LLM配置"""
        return self._config.llm

    def get_llm_api_config(self) -> LLMAPIConfig:
        """获取LLM API配置"""
        return self._config.llm.api

    def get_llm_model_config(self) -> LLMModelConfig:
        """获取LLM模型配置"""
        return self._config.llm.model

    def get_database_config(self) -> DatabaseConfig:
        """获取数据库配置"""
        return self._config.database

    def get_server_config(self) -> ServerConfig:
        """获取服务器配置"""
        return self._config.server

    def get_log_config(self) -> LogConfig:
        """获取日志配置"""
        return self._config.log


# 全局配置实例
yaml_config_manager = YAMLConfigManager()


def get_config() -> AppConfig:
    """获取全局配置"""
    return yaml_config_manager.get_config()


def get_llm_config() -> LLMConfig:
    """获取LLM配置"""
    return yaml_config_manager.get_llm_config()


def get_llm_api_config() -> LLMAPIConfig:
    """获取LLM API配置"""
    return yaml_config_manager.get_llm_api_config()


def get_llm_model_config() -> LLMModelConfig:
    """获取LLM模型配置"""
    return yaml_config_manager.get_llm_model_config()


def get_database_config() -> DatabaseConfig:
    """获取数据库配置"""
    return yaml_config_manager.get_database_config()


def get_server_config() -> ServerConfig:
    """获取服务器配置"""
    return yaml_config_manager.get_server_config()


def get_log_config() -> LogConfig:
    """获取日志配置"""
    return yaml_config_manager.get_log_config()